<?php
/**
 * 打包程序
 * @author Giles <giles.wang@icloud.com>
 *
 */
define('ROOT_PATH', realpath(dirname(__FILE__).DS).DS);


function  saveLog($message)
{
    $time = date('Y-m-d H:i:s');

    file_put_contents(ROOT_PATH.'sign.log', $time. '--'. $message. "\n", FILE_APPEND);
}


class packagesign
{

    public static $lastDir = array();
    public static $packName = '';


    /**
     * 重新签名
     * @param array $jobInfo     //任务信息
     * @param array $packInfo    //原包信息
     * @param array $perfileInfo //授权文件信息
     * @author Giles <giles.wang@icloud.com>
     * @return boole
     */
    public static function reSign($jobInfo, $packInfo, $perfileInfo,$bundleIds,$flag)
    {
        exec('security unlock-keychain "-p" "jufeng123" /Users/pack/Library/Keychains/login.keychain');
        $oldpackNameT = explode('.', $packInfo['packName']);
        $oldpackName  = $oldpackNameT[0];
        $itermid     = $perfileInfo['itermid'];
        $certificate = $perfileInfo['perfileCertificate'];
        $bundleId    = $bundleIds;
           saveLog('123'.$bundleId);
        saveLog('重新打包'.$packInfo['packName']);
        if($jobInfo['packType'] == 3) {
            $tmpFile = 'iiapple.entitlements';
        } else {
            $tmpFile = 'game.entitlements';
        }

        $md5cer      = md5($certificate);
        $channel     = $jobInfo['channel'];
        if(!is_file(ORIGIN_PAK.$packInfo['packName'])) {
            return array('error' => '1005', 'message' => '原包文件不存在,请查看原包');
        }
        if(self::$packName != $packInfo['packName']) {
            saveLog('删除Payload');
            exec('rm -rf '.ROOT_PATH.'Payload');
            saveLog('解压Payload '.$packInfo['packName']);
            exec("unzip -q " .ORIGIN_PAK.$packInfo['packName'], $actions, $cobak);
            //if($cobak != 0){
            //    saveLog('解压失败 '.$packInfo['packName']);
            //exec('rm -rf Payload');
            //    return array('error' => '1001', 'message' => '原包解压失败,请查看或者更换原包后重试');
            //};
            exec("chmod -R 777 Payload");
            self::$packName = $packInfo['packName'];
        }

        exec("chmod 777 ". $tmpFile);

        $dirs = self::getDir('Payload');
        saveLog($dirs);
        //下面这行注释了就是不改bundle id
        saveLog('修改INFO '.$packInfo['packName']);

        if($jobInfo['packType'] != 2) {
            exec("/usr/libexec/plistbuddy -c 'Set :CFBundleIdentifier \"" . $bundleId . "\"'  " . $dirs . "Info.plist");
        }
        $isAdd = "/usr/libexec/plistbuddy -c 'Add :CerBundleID String \"". $md5cer ."|".$channel."\"' ". $dirs ."Info.plist";
        exec($isAdd, $actions, $cobak);

        $setbundid = "/usr/libexec/plistbuddy -c 'Set :Bundle identifier \"".$bundleId."\"' ". $dirs ."Info.plist";
        exec($setbundid);

        if($cobak != 0) {
            $set = "/usr/libexec/plistbuddy -c 'Set :CerBundleID \"". $md5cer ."|".$channel."\"' ". $dirs ."Info.plist";
            exec($set);
        }
        if ($jobInfo['packType'] == 3) {
            exec("/usr/libexec/plistbuddy -c 'Set :APP_KEY \"". $perfileInfo['jpushappkey'] ."\"' ". $dirs ."PushConfig.plist");
        }
        saveLog('修改entitlements '.$packInfo['packName']);
        exec("/usr/libexec/plistbuddy -c 'Set :application-identifier \"". $itermid .".". $bundleId ."\"' ". $tmpFile);
        exec("/usr/libexec/plistbuddy -c 'Set :com.apple.developer.team-identifier \"". $itermid ."\"' " .$tmpFile);
        exec("/usr/libexec/plistbuddy -c 'Set :keychain-access-groups:0 \"". $itermid .".*\"' ".$tmpFile);
        if($md5cer == 'a91e8b9c5939a1bd1a78b18f44dfe283') {
            $cuk = 'E0FE75C0EFA9AF1EF9EADBB7E05D0165FFA915D5';
        } else {
            $cuk = $certificate;
        }
        saveLog('签名 '.$packInfo['packName']);

        if($jobInfo['packType'] == 2) {
            self::$lastDir = array();

            $appdirs = self::getAppDir('Payload');
            saveLog(var_export($appdirs, true));
            if(count($appdirs) == 0) {
                exec("cp ". PERFILE. $perfileInfo['name']." ".$dirs ."embedded.mobileprovision");
                $action = "/usr/bin/codesign -f -s \"".  $cuk ."\" --identifier \"". $bundleId ."\" --entitlements $tmpFile ". $dirs;
                saveLog('1:'. $action);
                exec($action, $actions, $cobak);
                if($cobak != 0){
                    exec('rm -rf Payload');
                    return array('error' => '1002', 'message' => '重签失败');
                };
            } else {
                foreach($appdirs as $appdir) {
                    exec("cp ". PERFILE. $perfileInfo['name']." ".$appdir ."embedded.mobileprovision");
                    $action = "/usr/bin/codesign -f -s \"".  $cuk ."\" --identifier \"". $bundleId ."\" --entitlements $tmpFile ". $appdir;
                    saveLog('2:'. $action);
                    exec($action, $actions, $cobak);
                    if($cobak != 0){
                        exec('rm -rf Payload');
                        return array('error' => '1002', 'message' => '重签失败');
                    };
                }
            }
        }

        exec("cp ". PERFILE. $perfileInfo['name']." ".$dirs ."embedded.mobileprovision");
        $action = "/usr/bin/codesign -f -s \"".  $cuk ."\" --identifier \"". $bundleId ."\" --entitlements $tmpFile ". $dirs;
        saveLog('3:'. $action);
        exec($action, $actions, $cobak);
        if($cobak != 0){
            //exec('rm -rf Payload');
            return array('error' => '1002', 'message' => '重签失败');
        };
        saveLog('打包 '.$packInfo['packName']);
        exec("zip -r -q temp.ipa Payload/");

        $filemd5 = md5_file('temp.ipa');

        if($channel == '1001000101') {
            $namechannel = 1;
        } else if($channel == '2001000101') {
            $namechannel = 2;
        } else if($channel == '3001000101') {
            $namechannel = 3;
        } else {
            $namechannel = 4;
        }

        if(!$flag){
             $fileNames = $filemd5 .'_'. $jobInfo['softId']. '_' .$namechannel .'_'.$oldpackName.'_'.$channel.'.ipa';}
        else {
              $fileNames = $filemd5 .'_'. $jobInfo['softId']. '_' .$namechannel .'_'.$oldpackName.'_'.$channel.'.ipa';}

        
        rename('temp.ipa', TRUE_PAK.$fileNames);
        //exec('rm -rf Payload');

        return array('error' => '0000', 'message' => $fileNames);
    }

    /**
     * SDK 重签
     *
     * @param $jobInfo
     * @param $packInfo
     * @param $perfileInfo
     * @return array
     */
    public static function sdkreSign($jobInfo, $packInfo, $perfileInfo,$bundleIds)
    {
        exec('security unlock-keychain "-p" "jufeng123" /Users/pack/Library/Keychains/login.keychain');

        if($jobInfo['channel'] == '3001000101') {
            $certificate = 'iPhone Developer: Zhibin Wang (7R28ZQL59M)';
            $bundleId    = $bundleIds;;
        } else {
            $certificate = $perfileInfo['perfileCertificate'];
            $bundleId    = $bundleIds;
        }

        $tmpFile = 'game.entitlements';

        saveLog('重新打包删除 '.$packInfo['packName']);
        exec('rm -rf PayloadSdk', $actions, $cobak);
        if($cobak != 0){
            saveLog('删除失败 '.$packInfo['packName']);
            return array('error' => '1005', 'message' => '删除失败');
        };
        saveLog('解压SDK '.$packInfo['packName']);
        exec("unzip -q " .ORIGIN_PAK.$packInfo['packName']);
        exec("chmod -R 777 PayloadSdk");

        $dirs = self::getSdkDir('PayloadSdk');

        $cuk = $certificate;
        $action = "/usr/bin/codesign --preserve-metadata=identifier,entitlements -f -s \"".  $cuk ."\" --identifier \"". $bundleId ."\" --entitlements $tmpFile ". $dirs;
        saveLog('3:'. $action);
        exec($action, $actions, $cobak);
        if($cobak != 0){
            //exec('rm -rf Payload');
            return array('error' => '1002', 'message' => '重签失败');
        };


        saveLog('打包 '.$packInfo['packName']);
        exec("zip -r -q temp.zip PayloadSdk/");
        exec("zip -r -q temp1.zip PayloadSdk/");

        $filemd5 = md5_file('temp.zip');
        $bundleMd5 = md5($bundleId);
        $cerMd5    = md5($cuk);
        $fileNames = $filemd5.'_'.$cerMd5 .'_'. $bundleMd5 .'_'. $jobInfo['softId'].'_'.$jobInfo['version'].'.zip';
        rename('temp.zip', PUSH_PAK.$fileNames);
        rename('temp1.zip', TRUE_PAK.$fileNames);

        return array('error' => '0000', 'message' => $fileNames);
    }

    /**
     * 软件重签路径获取
     * @param string $dir 路径
     *
     *
     */
    public static function getAppDir($dir)
    {
        //static $lastDir = array();
        if(!strpos($dir, '_CodeSignature')) {
            if (false != ($handle = opendir($dir))) {
                while ( false !== ($file = readdir($handle))) {
                    //去掉"“.”、“..”以及带“.xxx”后缀的文件
                    if((is_dir($dir."/".$file)) && $file!="." && $file!=".."){
                        if ($file == '_CodeSignature' && !strpos($dir, 'WatchKit App.app')) {

                            if(strpos($dir, ' ')) {
                                $dir = str_replace(' ', '\ ', $dir);
                            }
                            self::$lastDir[] = $dir.'/';
                        }

                        self::getAppDir($dir.'/'.$file);
                    }
                }
                //关闭句柄
                closedir ($handle);
            }

        }

        return array_reverse(self::$lastDir, TRUE);
    }

    /**
     * 获取 sdk 路径
     */
    public static function getSdkDir($dir)
    {
        $dirArray[]=NULL;
        if (false != ($handle = opendir($dir))) {
            $i=0;
            while ( false !== ($file = readdir($handle))) {
                //去掉"“.”、“..”以及带“.xxx”后缀的文件
                if (strpos($file, '.bundle')) {
                    $dirArray[$i]=$file;
                    $i++;
                }
            }
            //关闭句柄
            closedir ($handle);
        }
        $lastDir = $dir . '/'. $dirArray[0].'/';
        if(strpos($lastDir, ' ')) {
            $lastDir = str_replace(' ', '\ ', $lastDir);
        }
        return $lastDir;

    }

    /**
     * 获取解压后的包路径
     */
    public static function getDir($dir) {
        $dirArray[]=NULL;
        if (false != ($handle = opendir($dir))) {
            $i=0;
            while ( false !== ($file = readdir($handle))) {
                //去掉"“.”、“..”以及带“.xxx”后缀的文件
                if (strpos($file, '.app')) {
                    $dirArray[$i]=$file;
                    $i++;
                }
            }
            //关闭句柄
            closedir ($handle);
        }
        $lastDir = $dir . '/'. $dirArray[0].'/';
        if(strpos($lastDir, ' ')) {
            $lastDir = str_replace(' ', '\ ', $lastDir);
        }
        return $lastDir;
    }
}
